<?php
/* -------------------------------------------------------------------------------------
* 	ID:						$Id: class.cart.php 482 2014-01-30 16:22:27Z phone.mueller@googlemail.com $
* 	Letzter Stand:			$Revision: 482 $
* 	zuletzt geaendert von:	$Author: siekiera $
* 	Datum:					$Date: 2014-01-30 16:22:27 +0000 (Thu, 30 Jan 2014) $
*
* 	SEO:mercari by Siekiera Media
* 	http://www.seo-mercari.de
*
* 	Copyright (c) since 2011 SEO:mercari
* --------------------------------------------------------------------------------------
* 	based on:
* 	(c) 2000-2001 The Exchange Project  (earlier name of osCommerce)
* 	(c) 2002-2003 osCommerce - www.oscommerce.com
* 	(c) 2003     nextcommerce - www.nextcommerce.org
* 	(c) 2005     xt:Commerce - www.xt-commerce.com
*
* 	Released under the GNU General Public License
* ----------------------------------------------------------------------------------- */

require_once (DIR_FS_INC.'inc.create_random_value.php');
require_once (DIR_FS_INC.'inc.array_get_item.php');
require_once (DIR_FS_INC.'inc.get_prid.php');
require_once (DIR_FS_INC.'inc.draw_form.php');
require_once (DIR_FS_INC.'inc.draw_input_field.php');
require_once (DIR_FS_INC.'inc.image_submit.php');
require_once (DIR_FS_INC.'inc.get_tax_description.php');
require_once (DIR_WS_CLASSES.'class.product_konfigurator.php');

class cart {
	var $contents, $products, $total, $weight, $cartID, $content_type;
	var $dbTable;
	
	public function __construct() {
		$this->dbTable = 'BASKET';
		$this->reset();
	}
	
	public function use_konfigurator($from_logik, $products_id) {
    if ($from_logik && KONFIGURATOR_ENABLE == 'true') {
    	$konfigurator = new product_konfigurator($products_id);
    	return $konfigurator;
    }
    else
    	return false;
	}
	
	public function restore_contents() {
		global $db;
		if(!isset($_SESSION['customer_id']))
			return false;
			
		if(is_array($this->contents)) {
		reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				$qty = $this->contents[$products_id]['qty'];
				$product = $db->db_query("SELECT products_id FROM ".constant("TABLE_CUSTOMERS_".$this->dbTable)." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
				if($product->_numOfRows <= 0) {
					$db->db_query("INSERT INTO ".constant("TABLE_CUSTOMERS_".$this->dbTable)." (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) VALUES ('".$_SESSION['customer_id']."', '".$products_id."', '".$qty."', '".date('Ymd')."')");
					if(isset($this->contents[$products_id]['attributes'])) {
						reset($this->contents[$products_id]['attributes']);
						while(list ($option, $value) = each($this->contents[$products_id]['attributes'])) {
							$db->db_query("INSERT INTO ".constant("TABLE_CUSTOMERS_".$this->dbTable."_ATTRIBUTES")." (customers_id, products_id, products_options_id, products_options_value_id) VALUES ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')");
						}
					}
				} else
					$db->db_query("UPDATE ".constant("TABLE_CUSTOMERS_".$this->dbTable)." SET customers_basket_quantity = '".$qty."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
			}
		}

		// reset per-session cart contents, but not the database contents
		$this->reset(false);

		$products = $db->db_query("SELECT products_id, customers_basket_quantity FROM ".constant("TABLE_CUSTOMERS_".$this->dbTable)." WHERE customers_id = '".$_SESSION['customer_id']."'");
		while(!$products->EOF) {
  	  if ( ($konfigurator = $this->use_konfigurator(preg_match('/\d+{.*}/', $products->fields['products_id']),$products->fields['products_id'])) !== false ) {
        if (!$konfigurator->cart->add_cart($this, $products->fields['products_id'], $products->fields['customers_basket_quantity'], $konfigurator->parseProductKey($products->fields['products_id']), $this->dbTable, false))
          return;
      }
      else {
  			$this->contents[$products->fields['products_id']] = array ('qty' => $products->fields['customers_basket_quantity']);
  			$attributes = $db->db_query("SELECT
  											cpa.products_options_id, cpa.products_options_value_id
  										FROM
  											".constant("TABLE_CUSTOMERS_".$this->dbTable."_ATTRIBUTES")." cpa
  										WHERE
  											customers_id = '".$_SESSION['customer_id']."'
  										AND
  											products_id = '".$products->fields['products_id']."'");
											while(!$attributes->EOF) { 
    				$this->contents[$products->fields['products_id']]['attributes'][$attributes->fields['products_options_id']] = $attributes->fields['products_options_value_id'];
  				$attributes->MoveNext();
  			}
  		}
			$products->MoveNext();
		}
		$this->cleanup();
	}

	public function reset($reset_database = false) {
		global $db;
		$this->contents = array ();
		$this->total = 0;
		$this->tax = 0;
		$this->weight = 0;
		$this->content_type = false;

		if(isset($_SESSION['customer_id']) && ($reset_database == true)) {
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."'");
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." WHERE customers_id = '".$_SESSION['customer_id']."'");
		}

		unset ($this->cartID);
		if (isset ($_SESSION['cartID']))
			unset ($_SESSION['cartID']);
	}

	public function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
		global $new_products_id_in_cart, $db;
		$dummy_null = null;
    if ( ($konfigurator = $this->use_konfigurator(isset($_POST['KONFIGURATOR']), $_POST['products_id'])) !== false ) {
		if (!$konfigurator->cart->add_cart($dummy_null, $products_id, $qty, $attributes, $this->dbTable, $notify))
        return;
    }
    else {
  		$products_id = get_uprid($products_id, $attributes);

      if($this->in_cart($products_id))
        $this->update_quantity($products_id, $qty, $attributes);
      else {
        $this->contents[] = array($products_id);
  			$this->contents[$products_id] = array('qty' => $qty);

  			if(isset($_SESSION['customer_id']))
  				$db->db_query("INSERT INTO
  									".constant("TABLE_CUSTOMERS_".$this->dbTable)." (customers_id, products_id, customers_basket_quantity, customers_basket_date_added)
  								VALUES
  									('".$_SESSION['customer_id']."', '".$products_id."', '".$qty."', '".date('Ymd')."')");

  			if(is_array($attributes)) {
  				reset($attributes);
  				while(list($option, $value) = each($attributes)) {
  					$this->contents[$products_id]['attributes'][$option] = $value;
  					if (isset ($_SESSION['customer_id']))
  						$db->db_query("INSERT INTO
  											".constant("TABLE_CUSTOMERS_".$this->dbTable."_ATTRIBUTES")." (customers_id, products_id, products_options_id, products_options_value_id)
  										VALUES
  											('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')");
  				}
  			}
  		}

    }
 		if($notify == true)
      $_SESSION['new_products_id_in_cart'] = $products_id;

 		$this->cleanup();
 		$this->cartID = $this->generate_cart_id();
	}

	public function update_quantity($products_id, $quantity = '', $attributes = '') {
		global $db;

		if(empty($quantity))
			return true;

		$this->contents[$products_id]['qty'] = $quantity;

		if(isset($_SESSION['customer_id']))
			$db->db_query("UPDATE ".TABLE_CUSTOMERS_BASKET." SET customers_basket_quantity = '".$quantity."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");

		if(is_array($attributes)) {
			reset($attributes);
			while(list ($option, $value) = each($attributes)) {
				$this->contents[$products_id]['attributes'][$option] = $value;
				if(isset($_SESSION['customer_id']))
					$db->db_query("UPDATE ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." SET products_options_value_id = '".$value."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."' AND products_options_id = '".$option."'");
			}
		}
	}

	public function cleanup() {
		global $db;
		reset($this->contents);
		while(list ($key,) = each($this->contents)) {
			if($this->contents[$key]['qty'] < 1) {
				unset($this->contents[$key]);
				if(isset($_SESSION['customer_id'])) {
					$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$key."'");
					$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$key."'");
				}
			}
		}
	}

	public function count_contents() {
		$total_items = 0;
		if(is_array($this->contents)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents))
				$total_items += $this->get_quantity($products_id);
		}
		return $total_items;
	}

	public function get_quantity($products_id) {
		if(isset($this->contents[$products_id]))
			return $this->contents[$products_id]['qty'];
		else
			return 0;
	}

	public function in_cart($products_id) {
		if(isset($this->contents[$products_id]))
			return true;
		else
			return false;
	}

	public function remove($products_id) {
		global $db;
		if (isset($this->contents[$products_id])) {
		  unset($this->contents[$products_id]);
		  //$this->contents[$products_id] = NULL;
		}

		if(isset($_SESSION['customer_id'])) {
			$db->db_query("DELETE FROM ".constant("TABLE_CUSTOMERS_".$this->dbTable)." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
			$db->db_query("DELETE FROM ".constant("TABLE_CUSTOMERS_".$this->dbTable."_ATTRIBUTES")." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
		}
		$this->cartID = $this->generate_cart_id();
	}

	public function remove_all() {
		$this->reset();
	}

	public function get_product_id_list() {
		$product_id_list = '';
		if (is_array($this->contents)) {
			reset($this->contents);
			while (list ($products_id,) = each($this->contents))
				$product_id_list .= ', '.$products_id;
		}
		return substr($product_id_list, 2);
	}

    public function calculate() {
    	global $price, $db;
	    $this->total = 0;
	    $this->weight = 0;
	    $this->tax = array ();
	    $this->total_discount = array ();
	    if (!is_array($this->contents))
	    	return 0;
	    reset($this->contents);
  		$products = $this->get_products();

      foreach ($this->contents as $products_id => $products_value) {
        $qty = $this->contents[$products_id]['qty'];
        $product = $db->db_query("SELECT
        								products_id,
        								products_price,
        								products_discount_allowed,
        								products_tax_class_id,
        								products_weight
        							FROM
        								".TABLE_PRODUCTS."
        							WHERE
        								products_id='".get_prid($products_id)."'");
        if($product->_numOfRows) {
          if(($_price = $price->GetGroupPrice($product->fields['products_id'], $qty)) && ($_SESSION['customers_status']['customers_status_graduated_prices'] == 1))
            $single_q = $qty;
          else
            $single_q = 1;

				$products_price = $price->GetPrice($product->fields['products_id'], false, $single_q, $product->fields['products_tax_class_id'], $product->fields['products_price']);
				$this->total += $products_price * $qty;
          $this->weight += ($qty * $product->fields['products_weight']);
          $attribute_price = 0;
          if(isset($this->contents[$products_id]['attributes'])) {
            reset($this->contents[$products_id]['attributes']);
            while(list($option, $value) = each($this->contents[$products_id]['attributes'])) {
              $values = $price->GetOptionPrice($product->fields['products_id'], $option, $value);
              $this->weight 		+= $values['weight'] * $qty;
              $this->total 		+= $values['price'] * $qty;
              $attribute_price 	+= $values['price'];
            }
          }
          
				if($product->fields['products_tax_class_id'] != 0) {
					if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
						$products_price_tax = $products_price - ($products_price / 100 * $_SESSION['customers_status']['customers_status_ot_discount']);
						$attribute_price_tax = $attribute_price - ($attribute_price / 100 * $_SESSION['customers_status']['customers_status_ot_discount']);
					}
					$products_tax = $price->TAX[$product->fields['products_tax_class_id']];
					$products_tax_description = get_tax_description($product->fields['products_tax_class_id']);

					// Preis inkl. MwSt.
					if ($_SESSION['customers_status']['customers_status_show_price_tax'] == '1') {
						if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += ((($products_price_tax+$attribute_price_tax) / (100 + $products_tax)) * $products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_ADD_TAX."$products_tax_description";
						} else {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += ((($products_price+$attribute_price) / (100 + $products_tax)) * $products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_ADD_TAX."$products_tax_description";
						}
					}
					// Preis exkl. MwSt. + tax at checkout
					if ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1) {
						if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += (($products_price_tax+$attribute_price_tax) / 100) * ($products_tax)*$qty;
							$this->total_discount[$product->fields['products_tax_class_id']]+=(($products_price_tax+$attribute_price_tax) / 100) * ($products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_NO_TAX."$products_tax_description";
						} else {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += (($products_price+$attribute_price) / 100) * ($products_tax)*$qty;
							$this->total_discount[$product->fields['products_tax_class_id']]+=(($products_price+$attribute_price) / 100) * ($products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_NO_TAX."$products_tax_description";
						}
					}
				}
			}
		}
		foreach ($this->total_discount as $value) {
	      $this->total+=round($value, $price->get_decimal_places($order->info['currency']));
    }
	}

	public function attributes_price($products_id, $use_konfigurator = false) {
		global $price;
		if ( ($konfigurator = $this->use_konfigurator($use_konfigurator, $products_id)) !== false) {
      return $konfigurator->cart->options_price($products_id, $this);
		}
		else {
  		if(isset($this->contents[$products_id]['attributes'])) {
  			reset($this->contents[$products_id]['attributes']);
  			while(list($option, $value) = each($this->contents[$products_id]['attributes'])) {
  				$values = $price->GetOptionPrice($products_id, $option, $value);
  				$attributes_price += $values['price'];
  			}
  		}
  		return $attributes_price;
    }
	}

	public function get_products() {
    global $price, $main, $db;
    if (!is_array($this->contents))
      return false;
    $products_bak = $this->products;
    if(is_object($product))
      global $product;
    else
      $product = new product();
		
		$products_array = array();
		reset($this->contents);

		while(list($products_id,) = each($this->contents)) {
			if(isset($this->contents[$products_id]['qty']) 
          && $this->contents[$products_id]['qty'] != 0 
          && $this->contents[$products_id]['qty'] !=''){
          
        if (1==2 &&
            ($product_item = array_get_item($products_bak, 'id', $products_id)) !== false
            && $product_item['quantity'] == $this->contents[$products_id]['qty'] ){
          
          $products_array[] = $product_item;
        }
        else {
//        print_r($products_bak);
//        die($products_id);
  				$img = '';
  				$products = $db->db_query("SELECT distinct
  												p.products_id,
  												p.products_status,
  												pd.products_name,
  												p.product_template,
  												pd.products_description,
  												ifnull(pd.products_short_description, pd.products_description) products_short_description,
  												p.products_shippingtime,
  												p.products_image,
  												p.products_model,
  												p.products_price,
  												p.products_discount_allowed,
  												p.products_weight,
  												p.products_tax_class_id,
                    			if(ifnull(kpt.product_template, '') <> '', 1, 0) products_konfigurator
  											FROM
  												".TABLE_PRODUCTS." p
  												inner join ".TABLE_PRODUCTS_DESCRIPTION." pd
  													on pd.products_id = p.products_id
  													and pd.language_id = '".$_SESSION['languages_id']."'
                          left join ".TABLE_KONFIGURATOR_PRODUCT_TEMPLATES." kpt
                            on kpt.product_template = p.product_template
  											WHERE
  												p.products_id = '".get_prid($products_id)."'");
  				if($products->_numOfRows) {
  					$prid = $products->fields['products_id'];
  					$konfigurator_template = $products->fields['products_konfigurator'] == 1;
  
  					$products_price = $price->GetPrice($products->fields['products_id'], false, ($price->GetGroupPrice($products_id, $this->contents[$products_id]['qty']) ? $this->contents[$products_id]['qty'] : 1), $products->fields['products_tax_class_id']);
					
  					$desc = (CHECKOUT_PRODUCT_DETAIL == 'short' ? $products->fields['products_short_description'] : $products->fields['products_description']);
  					
  					$name_suffix = '';
  					if ($products->fields['products_status'] == 2) $name_suffix = 'Hausmodell';
  					if ($konfigurator_template) $name_suffix = 'konfiguriert';
					
  					$products_array[] = array(	'id' => $products_id,
              'name' => $products->fields['products_name'],
              'name_suffix' => $name_suffix,
              'desc' => $desc,
              'model' => $products->fields['products_model'],
              'image' => $product->productImage($products->fields['products_image'], 'icon'),
              'quantity' => $this->contents[$products_id]['qty'],
              'weight' => $products->fields['products_weight'],
              'shipping_time' => $main->getShippingStatusName($products->fields['products_shippingtime']),

              'price' => $products_price + $this->attributes_price($products_id, $konfigurator_template),
              'single_price' => $products_price,
              'final_price' => ($products_price + $this->attributes_price($products_id, $konfigurator_template)),
              'flat_price' => $products_price,
              'lot_price' => ($products_price + $this->attributes_price($products_id, $konfigurator_template))*$this->contents[$products_id]['qty'],

              'tax_class_id' => $products->fields['products_tax_class_id'],
              'attributes' => isset($this->contents[$products_id]['attributes']) ? $this->contents[$products_id]['attributes'] : array(),
              'options' => isset($this->contents[$products_id]['options']) ? $this->contents[$products_id]['options'] : array()
            );
  				}
  			}
			}
		}
   	$this->products = $products_array;
		return $products_array;
	}

	public function show_total() {
		$this->calculate();

		return $this->total;
	}

	public function show_weight() {
		$this->calculate();

		return round($this->weight, 2);
	}

	public function show_tax($format = true) {
		global $price;
		$this->calculate();
		$output = "";
		$val = 0;
        $gval = 0;

		foreach($this->tax as $key => $value) {
			if ($this->tax[$key]['value'] > 0 ) {
				$output .= $this->tax[$key]['desc'].": ".$price->format($this->tax[$key]['value'], true).'<br />';
        $gval+=$this->tax[$key]['value'];
			}
		}
		if($format)
			return $output;
		else
			return $gval;
	}

	public function generate_cart_id($length = 5) {
		return create_random_value($length, 'digits');
	}

	public function get_content_type() {
		global $db;

		$this->content_type = false;

		if((DOWNLOAD_ENABLED == 'true') && ($this->count_contents() > 0)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				if(isset($this->contents[$products_id]['attributes'])) {
					reset($this->contents[$products_id]['attributes']);
					while(list(, $value) = each($this->contents[$products_id]['attributes'])) {

						$virtual = $db->db_query("SELECT
														COUNT(*) AS total
													FROM
														".TABLE_PRODUCTS_ATTRIBUTES." pa,
														".TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD." pad
													WHERE
														pa.products_id = '".$products_id."'
													AND
														pa.options_values_id = '".$value."'
													AND
														pa.products_attributes_id = pad.products_attributes_id");

						if($virtual->fields['total'] > 0) {
							switch ($this->content_type) {
								case 'physical' :
									$this->content_type = 'mixed';
									return $this->content_type;
									break;

								default :
									#$this->content_type = 'virtual';
									$this->content_type = 'mixed';
									break;
							}
						} else {
							switch ($this->content_type) {
								case 'virtual' :
									$this->content_type = 'mixed';
									return $this->content_type;
									break;

								default :
									$this->content_type = 'physical';
									break;
							}
						}
					}
				} else {
					switch ($this->content_type) {
						case 'virtual' :
							$this->content_type = 'mixed';
							return $this->content_type;
							break;

						default :
							$this->content_type = 'physical';
							break;
					}
				}
			}
		} else {
			$this->content_type = 'physical';
		}
		return $this->content_type;
	}

	public function unserialize($broken) {
		for (reset($broken); $kv = each($broken);) {
			$key = $kv['key'];
			if (gettype($this-> $key) != "user function")
				$this-> $key = $kv['value'];
		}
	}

	// GV Code Start
	// ------------------------ ICW CREDIT CLASS Gift Voucher Addittion-------------------------------Start
	// amend count_contents to show nil contents for shipping
	// as we don't want to quote for 'virtual' item
	// GLOBAL CONSTANTS if NO_COUNT_ZERO_WEIGHT is true then we don't count any product with a weight
	// which is less than or equal to MINIMUM_WEIGHT
	// otherwise we just don't count gift certificates

	public function count_contents_virtual() { // get total number of items in cart disregard gift vouchers
		global $db;

		$total_items = 0;
		if(is_array($this->contents)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				$no_count = false;
				$gv_result = $db->db_query("SELECT products_model FROM ".TABLE_PRODUCTS." WHERE products_id = '".$products_id."'");
				if(preg_match('/^GIFT/', $gv_result->fields['products_model']))
					$no_count = true;

				if(NO_COUNT_ZERO_WEIGHT == 1) {
					$gv_result = $db->db_query("SELECT products_weight FROM ".TABLE_PRODUCTS." WHERE products_id = '".get_prid($products_id)."'");
					if($gv_result->fields['products_weight'] <= MINIMUM_WEIGHT)
						$no_count = true;
				}
				if(!$no_count)
					$total_items += $this->get_quantity($products_id);
			}
		}
		return $total_items;
	}
}